package com.aust.annotation;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.jar.JarOutputStream;

/**
 * 解析注解
 */
public class Test2 {
    public void parseClass() throws Exception {
        Class<Demo> demoClass = Demo.class;
        /**
         * 判断类上是否包含了某个注解
         */
        if (demoClass.isAnnotationPresent(Annotation4.class)) {
            /**
             * 一个类上可能包含多个注解(获取指定注解)
             */
            Annotation4 a = demoClass.getAnnotation(Annotation4.class);
            /**
             * 定义的注解其实在编译后，本质上就变成了一个接口
             * 所以当你通过反射拿到注解对象后，其实是拿到了 这个接口的代理对象，这个代理对象实现了这些方法，并能返回对应的值！
             * a.value() 等方法不是你自己定义的，是因为注解本质上是一个接口，这些方法就是注解属性的“getter”，而 JVM 会通过动态代理，自动返回 .class 文件中注解参数的值。
             */
            /**
             * 注解的底层实现本质上就是 Java 的动态代理机制！
             * 因为 Java 的动态代理只能代理接口！
             * 所以注解在本质上就是一个继承了 java.lang.annotation.Annotation 接口的特殊接口。
             */
            System.out.println(a.value());
            System.out.println(a.aaa());
            System.out.println(Arrays.toString(a.bbb()));

        }
        Method method = demoClass.getMethod("test1");
        /**
         * 判断方法上是否包含了某个注解
         */
        if (method.isAnnotationPresent(Annotation4.class)) {
            /**
             * 只是获取方法上面的注解与有无对象无关
             * 一个方法上可能包含多个注解(获取指定注解)
             */
            Annotation4 a = method.getAnnotation(Annotation4.class);
            System.out.println(a.value());
            System.out.println(a.aaa());
            System.out.println(Arrays.toString(a.bbb()));
        }
    }

    public static void main(String[] args) throws Exception {
        new Test2().parseClass();
    }
}
